<template>
  <div class="spots-page">
    <!-- 页面标题 -->
    <t-card class="header-card">
      <div class="card-header">
        <h2 class="page-title">景点管理</h2>
        <t-space>
          <t-button theme="primary" @click="handleCreateSpot">
            <template #icon><t-icon name="add" /></template>
            新增景点
          </t-button>
        </t-space>
      </div>
    </t-card>
    
    <!-- 搜索和筛选 -->
    <t-card class="filter-card">
      <t-form layout="inline" :data="searchForm" @reset="handleSearchReset" @submit="handleSearchSubmit">
        <t-form-item label="景点名称" name="keyword">
          <t-input
            v-model="searchForm.keyword"
            placeholder="请输入景点名称关键词"
            clearable
          />
        </t-form-item>
        <t-form-item label="分类" name="category">
          <t-select
            v-model="searchForm.category"
            placeholder="请选择分类"
            clearable
            style="width: 150px"
          >
            <t-option
              v-for="item in categoryOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </t-select>
        </t-form-item>
        <t-form-item label="状态" name="status">
          <t-select
            v-model="searchForm.status"
            placeholder="请选择状态"
            clearable
            style="width: 150px"
          >
            <t-option
              v-for="item in statusOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </t-select>
        </t-form-item>
        <t-form-item>
          <t-space>
            <t-button theme="primary" type="submit">
              <template #icon><t-icon name="search" /></template>
              搜索
            </t-button>
            <t-button theme="default" type="reset">重置</t-button>
          </t-space>
        </t-form-item>
      </t-form>
    </t-card>
    
    <!-- 景点列表表格 -->
    <t-card class="table-card">
      <t-table
        :data="spotList"
        :columns="columns"
        :row-key="rowKey"
        :loading="tableLoading"
        :pagination="pagination"
        :hover="true"
        @page-change="onPageChange"
      >
        <!-- 名称列 -->
        <template #name="{ row }">
          <div class="spot-name">
            {{ row.name }}
          </div>
        </template>
        
        <!-- 图片列 -->
        <template #imageUrl="{ row }">
          <div class="spot-thumbnail">
            <t-image
              :src="row.imageUrl"
              :style="{ width: '60px', height: '60px', objectFit: 'cover' }"
              fit="cover"
              shape="round"
            />
          </div>
        </template>
        
        <!-- 分类列 -->
        <template #category="{ row }">
          <t-tag theme="default" variant="light">{{ getCategoryLabel(row.category) }}</t-tag>
        </template>
        
        <!-- 状态列 -->
        <template #status="{ row }">
          <t-tag :theme="row.status === 'active' ? 'success' : 'warning'">
            {{ row.status === 'active' ? '启用' : '禁用' }}
          </t-tag>
        </template>
        
        <!-- 价格列 -->
        <template #ticketPrice="{ row }">
          {{ row.ticketPrice > 0 ? `¥${row.ticketPrice}` : '免费' }}
        </template>
        
        <!-- 操作列 -->
        <template #operation="{ row }">
          <t-space>
            <t-link theme="primary" hover="color" @click="handleEditSpot(row)">编辑</t-link>
            <t-link theme="primary" hover="color" @click="handlePreviewSpot(row)">预览</t-link>
            <t-link
              theme="primary"
              hover="color"
              @click="handleToggleStatus(row)"
            >
              {{ row.status === 'active' ? '禁用' : '启用' }}
            </t-link>
            <t-link
              theme="primary"
              hover="color"
              @click="handleViewOnMap(row)"
            >
              查看地图
            </t-link>
            <t-popconfirm
              content="确认删除该景点吗？该操作不可撤销。"
              @confirm="handleDeleteSpot(row)"
            >
              <t-link theme="danger" hover="color">删除</t-link>
            </t-popconfirm>
          </t-space>
        </template>
      </t-table>
    </t-card>
    
    <!-- 景点表单对话框 -->
    <t-dialog
      v-model:visible="dialogVisible"
      :header="formMode === 'create' ? '新增景点' : '编辑景点'"
      width="800px"
      :footer="false"
      @close="resetForm"
    >
      <t-form
        ref="form"
        :data="formData"
        :rules="rules"
        :label-width="100"
        @submit="handleFormSubmit"
      >
        <t-form-item label="景点名称" name="name">
          <t-input v-model="formData.name" placeholder="请输入景点名称" />
        </t-form-item>
        <t-form-item label="景点分类" name="category">
          <t-select
            v-model="formData.category"
            placeholder="请选择景点分类"
            clearable
          >
            <t-option
              v-for="item in categoryOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </t-select>
        </t-form-item>
        <t-form-item label="景点图片" name="imageUrl">
          <t-upload
            v-model="formData.imageUrl"
            theme="image"
            accept="image/*"
            :action="uploadAction"
            :before-upload="handleBeforeUpload"
            :max="1"
            :format-response="formatUploadResponse"
          >
            <template #tip>
              <p class="upload-tip">支持.jpg .jpeg .png格式，大小不超过2M</p>
            </template>
          </t-upload>
        </t-form-item>
        <t-form-item label="景点标签" name="tags">
          <t-input-tag v-model="formData.tags" placeholder="输入标签后按回车添加" clearable />
        </t-form-item>
        <t-form-item label="景点地址" name="address">
          <t-input v-model="formData.address" placeholder="请输入详细地址" />
        </t-form-item>
        <t-form-item label="地图位置">
          <t-row :gutter="[16, 16]">
            <t-col :span="12">
              <t-form-item label="经度" name="longitude">
                <t-input-number v-model="formData.longitude" placeholder="请输入经度" />
              </t-form-item>
            </t-col>
            <t-col :span="12">
              <t-form-item label="纬度" name="latitude">
                <t-input-number v-model="formData.latitude" placeholder="请输入纬度" />
              </t-form-item>
            </t-col>
          </t-row>
          <t-button theme="default" @click="openMapSelector">
            <template #icon><t-icon name="map" /></template>
            地图选点
          </t-button>
        </t-form-item>
        <t-form-item label="门票价格" name="ticketPrice">
          <t-input-number v-model="formData.ticketPrice" placeholder="请输入门票价格" min="0" />
        </t-form-item>
        <t-form-item label="联系电话" name="contactPhone">
          <t-input v-model="formData.contactPhone" placeholder="请输入联系电话" />
        </t-form-item>
        <t-form-item label="开放时间" name="openingHours">
          <t-input v-model="formData.openingHours" placeholder="例如：09:00-18:00" />
        </t-form-item>
        <t-form-item label="景点描述" name="description">
          <t-textarea
            v-model="formData.description"
            placeholder="请输入景点详细描述"
            :autosize="{ minRows: 4, maxRows: 8 }"
          />
        </t-form-item>
        <t-form-item label="状态" name="status">
          <t-radio-group v-model="formData.status">
            <t-radio value="active">启用</t-radio>
            <t-radio value="inactive">禁用</t-radio>
          </t-radio-group>
        </t-form-item>
        <t-form-item>
          <t-space>
            <t-button theme="default" @click="dialogVisible = false">取消</t-button>
            <t-button theme="primary" type="submit" :loading="submitLoading">确定</t-button>
          </t-space>
        </t-form-item>
      </t-form>
    </t-dialog>
    
    <!-- 景点预览对话框 -->
    <t-dialog
      v-model:visible="previewVisible"
      header="景点预览"
      width="800px"
      :footer="false"
    >
      <div class="spot-preview" v-if="previewData">
        <h1 class="preview-title">{{ previewData.name }}</h1>
        <div class="preview-meta">
          <t-tag theme="default" variant="light">{{ getCategoryLabel(previewData.category) }}</t-tag>
          <t-tag :theme="previewData.status === 'active' ? 'success' : 'warning'">
            {{ previewData.status === 'active' ? '启用' : '禁用' }}
          </t-tag>
        </div>
        <div class="preview-image" v-if="previewData.imageUrl">
          <t-image :src="previewData.imageUrl" fit="contain" :style="{ maxHeight: '300px' }" />
        </div>
        <div class="preview-info">
          <div class="info-item">
            <i class="t-icon t-icon-location"></i>
            <span>{{ previewData.address }}</span>
          </div>
          <div class="info-item">
            <i class="t-icon t-icon-money-circle"></i>
            <span>门票：{{ previewData.ticketPrice > 0 ? `¥${previewData.ticketPrice}` : '免费' }}</span>
          </div>
          <div class="info-item">
            <i class="t-icon t-icon-call"></i>
            <span>联系电话：{{ previewData.contactPhone || '暂无' }}</span>
          </div>
          <div class="info-item">
            <i class="t-icon t-icon-time"></i>
            <span>开放时间：{{ previewData.openingHours || '暂无' }}</span>
          </div>
        </div>
        <div class="preview-tags" v-if="previewData.tags && previewData.tags.length">
          <t-tag v-for="(tag, index) in previewData.tags" :key="index" theme="primary" variant="light" :style="{ margin: '0 4px 4px 0' }">
            {{ tag }}
          </t-tag>
        </div>
        <div class="preview-description">
          <h3>景点描述</h3>
          <div class="description-content">{{ previewData.description }}</div>
        </div>
      </div>
    </t-dialog>
    
    <!-- 地图查看对话框 -->
    <t-dialog
      v-model:visible="mapVisible"
      header="景点位置"
      width="800px"
      :footer="false"
    >
      <div class="map-container" v-if="selectedSpot">
        <div id="map" style="width: 100%; height: 400px;"></div>
        <div class="map-info">
          <p><strong>景点名称：</strong>{{ selectedSpot.name }}</p>
          <p><strong>详细地址：</strong>{{ selectedSpot.address }}</p>
          <p><strong>经纬度：</strong>{{ selectedSpot.longitude }}, {{ selectedSpot.latitude }}</p>
        </div>
      </div>
    </t-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { MessagePlugin } from 'tdesign-vue-next'
import type { PrimaryTableCol, TableRowData, PageInfo } from 'tdesign-vue-next'
import {
  getSpots,
  getSpotDetail,
  createSpot,
  updateSpot,
  deleteSpot,
  updateSpotStatus,
  uploadSpotImage,
  getSpotCategories,
  type Spot,
  type SpotFormData
} from '../../../api/content/spots'

// 表格列定义
const columns: PrimaryTableCol[] = [
  {
    colKey: 'name',
    title: '景点名称',
    width: 180,
    cell: 'name'
  },
  {
    colKey: 'imageUrl',
    title: '图片',
    width: 100,
    cell: 'imageUrl'
  },
  {
    colKey: 'category',
    title: '分类',
    width: 100,
    cell: 'category'
  },
  {
    colKey: 'address',
    title: '地址',
    width: 200
  },
  {
    colKey: 'ticketPrice',
    title: '门票价格',
    width: 100,
    cell: 'ticketPrice'
  },
  {
    colKey: 'status',
    title: '状态',
    width: 100,
    cell: 'status'
  },
  {
    colKey: 'operation',
    title: '操作',
    fixed: 'right',
    width: 280,
    cell: 'operation'
  }
]

// 表格数据
const spotList = ref<Spot[]>([])
const tableLoading = ref(false)
const rowKey = 'id'

// 分页配置
const pagination = reactive({
  current: 1,
  pageSize: 10,
  total: 0
})

// 搜索表单
const searchForm = reactive({
  keyword: '',
  category: '',
  status: ''
})

// 景点分类选项
const categoryOptions = ref<Array<{value: string, label: string}>>([
  { value: 'nature', label: '自然风光' },
  { value: 'culture', label: '人文景观' },
  { value: 'history', label: '历史遗址' },
  { value: 'religion', label: '宗教圣地' },
  { value: 'leisure', label: '休闲娱乐' },
  { value: 'other', label: '其他' }
])

// 景点状态选项
const statusOptions = [
  { value: 'active', label: '启用' },
  { value: 'inactive', label: '禁用' }
]

// 表单数据
const formMode = ref<'create' | 'edit'>('create')
const dialogVisible = ref(false)
const submitLoading = ref(false)
const form = ref(null)

// 表单初始化数据
const defaultFormData: SpotFormData = {
  name: '',
  imageUrl: '',
  category: '',
  address: '',
  longitude: 0,
  latitude: 0,
  description: '',
  tags: [],
  ticketPrice: 0,
  contactPhone: '',
  openingHours: '',
  status: 'active'
}

// 表单数据
const formData = reactive<SpotFormData>({ ...defaultFormData })

// 表单验证规则
const rules = {
  name: [{ required: true, message: '请输入景点名称', type: 'error' }],
  category: [{ required: true, message: '请选择景点分类', type: 'error' }],
  imageUrl: [{ required: true, message: '请上传景点图片', type: 'error' }],
  address: [{ required: true, message: '请输入景点地址', type: 'error' }],
  longitude: [{ required: true, message: '请输入经度', type: 'error' }],
  latitude: [{ required: true, message: '请输入纬度', type: 'error' }],
  description: [{ required: true, message: '请输入景点描述', type: 'error' }]
}

// 预览数据
const previewVisible = ref(false)
const previewData = ref<Spot | null>(null)

// 地图查看
const mapVisible = ref(false)
const selectedSpot = ref<Spot | null>(null)

// 上传配置
const uploadAction = '/api/upload/spot'

// 初始化数据
onMounted(() => {
  fetchSpotList()
  fetchCategories()
})

// 获取景点列表
const fetchSpotList = async () => {
  tableLoading.value = true
  try {
    const { data } = await getSpots({
      page: pagination.current,
      pageSize: pagination.pageSize,
      keyword: searchForm.keyword || undefined,
      category: searchForm.category || undefined,
      status: searchForm.status || undefined
    })
    
    // 模拟数据
    spotList.value = data || []
    pagination.total = data?.length || 0
  } catch (error) {
    console.error('获取景点列表失败', error)
    MessagePlugin.error('获取景点列表失败')
  } finally {
    tableLoading.value = false
  }
}

// 获取分类列表
const fetchCategories = async () => {
  try {
    const { data } = await getSpotCategories()
    if (data && data.length > 0) {
      categoryOptions.value = data
    }
  } catch (error) {
    console.error('获取分类列表失败', error)
  }
}

// 获取分类标签
const getCategoryLabel = (value: string) => {
  const category = categoryOptions.value.find(item => item.value === value)
  return category ? category.label : value
}

// 分页变化
const onPageChange = (pageInfo: PageInfo) => {
  pagination.current = pageInfo.current
  pagination.pageSize = pageInfo.pageSize
  fetchSpotList()
}

// 搜索表单提交
const handleSearchSubmit = () => {
  pagination.current = 1
  fetchSpotList()
}

// 搜索表单重置
const handleSearchReset = () => {
  pagination.current = 1
  fetchSpotList()
}

// 创建景点
const handleCreateSpot = () => {
  formMode.value = 'create'
  Object.assign(formData, defaultFormData)
  dialogVisible.value = true
}

// 编辑景点
const handleEditSpot = async (row: Spot) => {
  formMode.value = 'edit'
  dialogVisible.value = true
  submitLoading.value = true
  
  try {
    const { data } = await getSpotDetail(row.id)
    if (data) {
      // 填充表单数据
      Object.assign(formData, data)
    }
  } catch (error) {
    console.error('获取景点详情失败', error)
    MessagePlugin.error('获取景点详情失败')
    dialogVisible.value = false
  } finally {
    submitLoading.value = false
  }
}

// 预览景点
const handlePreviewSpot = async (row: Spot) => {
  try {
    const { data } = await getSpotDetail(row.id)
    if (data) {
      previewData.value = data
      previewVisible.value = true
    }
  } catch (error) {
    console.error('获取景点详情失败', error)
    MessagePlugin.error('获取景点详情失败')
  }
}

// 切换景点状态
const handleToggleStatus = async (row: Spot) => {
  try {
    const newStatus = row.status === 'active' ? 'inactive' : 'active'
    await updateSpotStatus(row.id, newStatus)
    MessagePlugin.success('状态更新成功')
    fetchSpotList()
  } catch (error) {
    console.error('更新景点状态失败', error)
    MessagePlugin.error('更新景点状态失败')
  }
}

// 查看地图
const handleViewOnMap = (row: Spot) => {
  selectedSpot.value = row
  mapVisible.value = true
  
  // 在下一个事件循环中初始化地图
  setTimeout(() => {
    initMap(row.longitude, row.latitude, row.name)
  }, 100)
}

// 初始化地图
const initMap = (longitude: number, latitude: number, title: string) => {
  // 注意：这里仅为示例，实际项目中需要集成真实的地图SDK
  // 如腾讯地图、百度地图、高德地图等
  
  // 模拟地图初始化，实际项目中请替换为真实地图API调用
  const mapElement = document.getElementById('map')
  if (mapElement) {
    mapElement.innerHTML = `
      <div style="text-align: center; padding: 20px;">
        <p>这里将显示地图，经度：${longitude}，纬度：${latitude}</p>
        <p>景点名称：${title}</p>
        <div style="background-color: #f0f0f0; height: 300px; display: flex; align-items: center; justify-content: center;">
          <span>地图加载区域</span>
        </div>
      </div>
    `
  }
}

// 打开地图选点器
const openMapSelector = () => {
  // 注意：这里仅为示例，实际项目中需要集成真实的地图选点功能
  MessagePlugin.info('地图选点功能需要集成实际的地图SDK')
  
  // 模拟选点结果
  setTimeout(() => {
    // 贵州省贵阳市的经纬度（示例）
    formData.longitude = 106.7091
    formData.latitude = 26.5791
    MessagePlugin.success('已选择地图位置')
  }, 1000)
}

// 删除景点
const handleDeleteSpot = async (row: Spot) => {
  try {
    await deleteSpot(row.id)
    MessagePlugin.success('删除成功')
    fetchSpotList()
  } catch (error) {
    console.error('删除景点失败', error)
    MessagePlugin.error('删除景点失败')
  }
}

// 上传前检查
const handleBeforeUpload = (file: File) => {
  const isImage = /image\/\w+/.test(file.type)
  const isLt2M = file.size / 1024 / 1024 < 2
  
  if (!isImage) {
    MessagePlugin.error('只能上传图片文件！')
    return false
  }
  
  if (!isLt2M) {
    MessagePlugin.error('图片大小不能超过2MB！')
    return false
  }
  
  return true
}

// 格式化上传响应
const formatUploadResponse = (res: any) => {
  if (res.code === 0 && res.data) {
    return res.data.url
  }
  return ''
}

// 提交表单
const handleFormSubmit = async () => {
  submitLoading.value = true
  try {
    if (formMode.value === 'create') {
      await createSpot(formData)
      MessagePlugin.success('创建成功')
    } else {
      await updateSpot(formData.id!, formData)
      MessagePlugin.success('更新成功')
    }
    dialogVisible.value = false
    fetchSpotList()
  } catch (error) {
    console.error('提交失败', error)
    MessagePlugin.error('提交失败')
  } finally {
    submitLoading.value = false
  }
}

// 重置表单
const resetForm = () => {
  Object.assign(formData, defaultFormData)
}
</script>

<style scoped>
.spots-page {
  padding: 20px;
}

.header-card {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.page-title {
  margin: 0;
  font-size: 20px;
  font-weight: 500;
}

.filter-card {
  margin-bottom: 20px;
}

.table-card {
  margin-bottom: 20px;
}

.spot-name {
  font-weight: 500;
}

.upload-tip {
  margin-top: 8px;
  font-size: 12px;
  color: rgba(0, 0, 0, 0.4);
}

.spot-preview {
  padding: 0 16px;
}

.preview-title {
  margin-top: 0;
  margin-bottom: 16px;
  font-size: 24px;
  text-align: center;
}

.preview-meta {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin-bottom: 20px;
}

.preview-image {
  text-align: center;
  margin-bottom: 24px;
}

.preview-info {
  padding: 16px;
  background-color: rgba(0, 0, 0, 0.02);
  border-radius: 8px;
  margin-bottom: 24px;
}

.info-item {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
}

.info-item i {
  margin-right: 8px;
  color: rgba(0, 0, 0, 0.4);
}

.preview-tags {
  margin-bottom: 24px;
}

.preview-description h3 {
  font-size: 16px;
  margin-bottom: 12px;
}

.description-content {
  white-space: pre-line;
  line-height: 1.6;
}

.map-container {
  display: flex;
  flex-direction: column;
}

.map-info {
  margin-top: 16px;
  padding: 16px;
  background-color: rgba(0, 0, 0, 0.02);
  border-radius: 8px;
}
</style> 